// 有序块的存放位置
// R 81~96 S 132~163
/*
交操作算法。大体思路与t4相近，
差别在于连接的时候判断条件变成判断两个关系的元组是否完全相等而不是X相等，
且在数据写入时只需要写入其中一个元组的数据即可。
*/
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include "extmem.h"
#include "t2.h"
#include "t4.h"
int crossR_S(Buffer *buf,int RBlkNo,int SBlkNo,int Rlength,int Slength,int wf);
int main(int argc, char const *argv[])
{
    Buffer buf;
    if (!initBuffer(520, 64, &buf))
    {
        perror("Buffer Initialization Failed!\n");
        return -1;
    }
    int count;
    count=crossR_S(&buf,81,132,16,32,500);
    printf("--------------------");
    printf("\nFound num:%d\n",count);
    printf("\nBuf IO num:%ld\n",buf.numIO);
    return 0;
}

// 做关系R和S的交`
int crossR_S(Buffer *buf,int RBlkNo,int SBlkNo,int Rlength,int Slength,int wf)
{
    int Rlast=RBlkNo+Rlength-1;
    int Slast=SBlkNo+Slength-1;
    unsigned char *Rbuf=readBlockFromDisk(RBlkNo++,buf);
    unsigned char *Sbuf=readBlockFromDisk(SBlkNo++,buf);
    unsigned char *wbuf=getNewBlockInBuffer(buf);
    int wp=0;
    int count=0;
    int rp,sp;
    int RX,SX;
    int RY,SY;
    rp=sp=0;
    getValueByp(&RX,&RY,rp,Rbuf);
    getValueByp(&SX,&SY,sp,Sbuf);
    while(1)
    {
        if (RX>SX)
        {
            sp+=8;
            if (sp==56)
            {
                sp=0;
                freeBlockInBuffer(Sbuf,buf);
                if (SBlkNo<=Slast)
                {
                    Sbuf=readBlockFromDisk(SBlkNo++,buf);
                }
                else
                {
                    if (wp!=0)
                    {
                        memset(wbuf+wp,0,sizeof(char)*64-wp);
                        writeBlockToDisk(wbuf,wf,buf);
                    }
                    return count;
                }
            }
            getValueByp(&SX,&SY,sp,Sbuf);
        }
        else if (RX<SX)
        {
            rp+=8;
            if (rp==56)
            {
                rp=0;
                freeBlockInBuffer(Rbuf,buf);
                if (RBlkNo<=Rlast)
                {
                    Rbuf=readBlockFromDisk(RBlkNo++,buf);
                }
                else
                {
                    if (wp!=0)
                    {
                        memset(wbuf+wp,0,sizeof(char)*64-wp);
                        writeBlockToDisk(wbuf,wf,buf);
                    }
                    return count;
                }
            }
            getValueByp(&RX,&RY,rp,Rbuf);
        }
        // 大体遍历过程和join差不多，多一个选择再输出
        else
        {
            int sp_pre=sp;
            int SBlkNo_pre=SBlkNo-1;
            do
            {
                // 用于标注此时SBuf是否存在
                int sflag=1;
                do
                {
                    // X,Y都相同才输出
                    if (RY==SY)
                    {
                        printf("-----------------------");
                        // printf("\ncount:%d",++count);
                        count++;
                        printf("\nRBlk:%d,rp:%d\n",RBlkNo-1,rp);
                        // printf("\nRX:%d RY:%d\n",RX,RY);
                        printf("\nSBlk:%d,sp:%d\n",SBlkNo-1,sp);
                        printf("\nX:%d Y:%d\n",SX,SY);
                        writeData2(sp,&wp,Sbuf,wbuf,&wf,buf);
                    }
                    sp+=8;
                    if (sp==56)
                    {
                        sp=0;
                        freeBlockInBuffer(Sbuf,buf);
                        sflag=0;
                        if (SBlkNo<=Slast)
                        {
                            Sbuf=readBlockFromDisk(SBlkNo++,buf);
                            sflag=1;
                        }
                        else
                        {
                            break;
                        }
                    }
                    getValueByp(&SX,&SY,sp,Sbuf);
                } while (SX==RX);
                if (sflag)
                {
                    freeBlockInBuffer(Sbuf,buf);
                }
                // 回位
                SBlkNo=SBlkNo_pre;
                Sbuf=readBlockFromDisk(SBlkNo++,buf);
                sp=sp_pre;
                rp+=8;
                if (rp==56)
                {
                    rp=0;
                    freeBlockInBuffer(Rbuf,buf);
                    if (RBlkNo<Rlast)
                    {
                        Rbuf=readBlockFromDisk(RBlkNo++,buf);
                    }
                    else
                    {
                        if (wp!=0)
                        {
                            memset(wbuf+wp,0,sizeof(char)*64-wp);
                            writeBlockToDisk(wbuf,wf,buf);
                        }
                        return count;
                    }
                }
                // 回位后要重新get一遍
                getValueByp(&SX,&SY,sp,Sbuf);
                getValueByp(&RX,&RY,rp,Rbuf);
            } while (RX==SX);
        }
        
        
    }
}